﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Linq;
using Codeplex.CRMQuery;
using Microsoft.VisualStudio.TestTools.UnitTesting;


namespace Codeplex.CRMQuery.UnitTest
{
    [TestClass]
    public class UnitTest
    {

        /// <summary>
        /// Tests Created, Udpate and Delete functionality
        /// </summary>
        [TestMethod]
        public void TestCreateUpdateDelete()
        {
            string firstName = "firstname" + (new System.Random()).Next().ToString();
            string lastName = "lastname" + (new System.Random()).Next().ToString();

            CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString);

            Crm_Contact newContact = new Crm_Contact()
            {
                Firstname = firstName,
                Lastname = lastName
            };

            // Test Insert

            dc.Crm_Contacts.InsertOnSubmit(newContact);
            dc.SubmitChanges();

            Assert.IsTrue(newContact.Contactid.HasValue);

            // Force a new data context
            dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString);

            Crm_Contact createdContact = dc.Crm_Contacts.Where(c => c.Contactid == newContact.Contactid.Value).FirstOrDefault();

            Assert.IsTrue(createdContact.Firstname == firstName);
            Assert.IsTrue(createdContact.Lastname == lastName);

            // Test update

            createdContact.Firstname = "Updated" + createdContact.Firstname;
            createdContact.Lastname = "Updated" + createdContact.Lastname;

            dc.SubmitChanges();

            // Force a new data context
            dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString);

            Crm_Contact updatedContact = dc.Crm_Contacts.Where(c => c.Contactid == newContact.Contactid.Value).FirstOrDefault();

            Assert.IsTrue(updatedContact.Firstname == "Updated" + firstName);
            Assert.IsTrue(updatedContact.Lastname == "Updated" + lastName);

            // Test delete
            dc.Crm_Contacts.DeleteOnSubmit(updatedContact);
            dc.SubmitChanges();

            dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString);
            Crm_Contact deletedContact = dc.Crm_Contacts.Where(c => c.Contactid == newContact.Contactid.Value).FirstOrDefault();

            Assert.IsTrue(deletedContact == null);
        }


        /// <summary>
        /// Tests that LoadWith is brining back correct results
        /// </summary>
        [TestMethod]
        public void TestLoadWith()
        {
            // Create a contact
            string firstName = "firstname" + (new System.Random()).Next().ToString();
            string lastName = "lastname" + (new System.Random()).Next().ToString();
            Guid contactId = Guid.NewGuid();

            CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString);

            Crm_Contact newContact = new Crm_Contact()
            {
                Contactid = contactId,
                Firstname = firstName,
                Lastname = lastName
            };

            dc.Crm_Contacts.InsertOnSubmit(newContact);
            dc.SubmitChanges();


            // Test Load parent entities (2 levels)          
            dc = new CrmDataContext(Properties.Settings.Default.ConnectionString);
            DataLoadOptions lo = new DataLoadOptions();
            lo.LoadWith<Crm_Contact>(c => c.Contact_Owning_User);
            lo.LoadWith<Crm_Systemuser>(su => su.Business_Unit_System_User);
            dc.DeferredLoadingEnabled = false;
            dc.LoadOptions = lo;

            List<Crm_Contact> parentResults = dc.Crm_Contacts.Where(c => c.Contactid == contactId).ToList();
            Assert.IsTrue(parentResults.Count > 0);
            Assert.IsTrue(parentResults[0].Contact_Owning_User != null);
            Assert.IsTrue(parentResults[0].Contact_Owning_User.Businessunitid != null);
            Assert.IsTrue(parentResults[0].Contact_Owning_User.Business_Unit_System_User != null);

            // Test Load Child entities
            Guid userId = parentResults[0].Contact_Owning_User.Systemuserid.Value;

            dc = new CrmDataContext(Properties.Settings.Default.ConnectionString);
            lo = new DataLoadOptions();
            lo.LoadWith<Crm_Systemuser>(su => su.Contact_Owning_Users);
            dc.DeferredLoadingEnabled = false;
            dc.LoadOptions = lo;

            List<Crm_Systemuser> childResults = dc.Crm_Systemusers.Where(su => su.Systemuserid == userId).ToList();
            Assert.IsTrue(childResults.Count == 1);
            Assert.IsTrue(childResults[0].Contact_Owning_Users.Count > 0);
        }

        /// <summary>
        /// Tests Many to Many Retrieval
        /// </summary>
        [TestMethod]
        public void TestManyToMany()
        {
            string firstName = "firstname" + (new System.Random()).Next().ToString();
            string lastName = "lastname" + (new System.Random()).Next().ToString();
            Guid contactId = Guid.NewGuid();
            Guid leadId = Guid.NewGuid();

            using (CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString))
            {
                // Create A Contact
                Crm_Contact newContact = new Crm_Contact()
                {
                    Contactid = contactId,
                    Firstname = firstName,
                    Lastname = lastName
                };

                dc.Crm_Contacts.InsertOnSubmit(newContact);

                // Create A Lead        
                Crm_Lead newLead = new Crm_Lead()
                {
                    Leadid = leadId,
                    Firstname = firstName,
                    Lastname = lastName
                };

                dc.Crm_Leads.InsertOnSubmit(newLead);

                // Create a M to M relationship between lead and contact
                Crm_Contactleads newContactLead = new Crm_Contactleads();
                newContactLead.Crm_Contact = newContact;
                newContactLead.Crm_Lead = newLead;

                dc.Crm_Contactleads.InsertOnSubmit(newContactLead);

                dc.SubmitChanges();
            }

            using (CrmDataContext dc = new CrmDataContext(Properties.Settings.Default.ConnectionString))
            {
                // Navigate from contact to lead
                Crm_Contact test1 = (from c in dc.Crm_Contacts
                                     where c.Contactid == contactId
                                     select c).FirstOrDefault();

                Assert.IsTrue(test1.Contactleads_Associations.Count() > 0);
                Assert.IsNotNull(test1.Contactleads_Associations.FirstOrDefault());
                Assert.IsTrue(test1.Contactleads_Associations.First().Crm_Lead.Leadid == leadId);
            }

            using (CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString))
            {
                // Navigate from lead to contact

                Crm_Lead test2 = (from l in dc.Crm_Leads
                                  where l.Leadid == leadId
                                  select l).FirstOrDefault();

                Assert.IsTrue(test2.Contactleads_Associations.Count() > 0);
                Assert.IsNotNull(test2.Contactleads_Associations.FirstOrDefault());
                Assert.IsTrue(test2.Contactleads_Associations.First().Crm_Contact.Contactid == contactId);

                bool pass1 = false;

                // Attempt an update (should not work, so look for exception)
                try
                {
                    test2.Contactleads_Associations.First().Crm_Contact = new Crm_Contact();
                    dc.SubmitChanges();
                }
                catch (CrmUpdateException crmupex)
                {
                    pass1 = true;
                }

                Assert.IsTrue(pass1);
            }

            using (CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString))
            {
                // Delete the intersect                
                var test3 = from intersect in dc.Crm_Contactleads
                            where intersect.Leadid == leadId
                            select intersect;

                dc.Crm_Contactleads.DeleteAllOnSubmit(test3.ToList());
                dc.SubmitChanges();
            }

        }



        [TestMethod]
        public void CreateEmailWithActivityParties()
        {

            string firstName = "firstname" + (new System.Random()).Next().ToString();
            string lastName = "lastname" + (new System.Random()).Next().ToString();
            string subject = "subject" + (new System.Random()).Next().ToString();
            string body = "body" + (new System.Random()).Next().ToString();

            Guid contactId = Guid.NewGuid();

            using (CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString))
            {

                // Create A Contact
                Crm_Contact newContact = new Crm_Contact()
                {
                    Contactid = contactId,
                    Firstname = firstName,
                    Lastname = lastName
                };

                dc.Crm_Contacts.InsertOnSubmit(newContact);

                Crm_Email newEmail = new Crm_Email();

                newEmail.Subject = subject;
                newEmail.Description = body;

                Crm_Activityparty party = new Crm_Activityparty() { Activitypartyid = Guid.NewGuid(), Partyid = newContact.Contactid, Partyidtypecode = CRMQuery.Common.SystemEntityTypeCodes.Contact, Participationtypemask = Crm_Activityparty.Lists.Participationtypemasks.ToRecipient };

                newEmail.Email_Activity_Parties.Add(party);
                dc.Crm_Emails.InsertOnSubmit(newEmail);
                dc.SubmitChanges();


            }

        }

        [TestMethod]
        public void CreateAnnotation()
        {
            using (CrmDataContext dc = new CrmDataContext(CrmHelper.GetCrmService(), CrmHelper.GetCrmMetadataService(), Properties.Settings.Default.ConnectionString))
            {

                string firstName = "firstname" + (new System.Random()).Next().ToString();
                string lastName = "lastname" + (new System.Random()).Next().ToString();
                Guid contactId = Guid.NewGuid();

                // Create a Contact
                Crm_Contact newContact = new Crm_Contact()
                {
                    Contactid = contactId,
                    Firstname = firstName,
                    Lastname = lastName,
                };

                dc.Crm_Contacts.InsertOnSubmit(newContact);

                dc.SubmitChanges();

                // Create a note
                Crm_Annotation newNote = new Crm_Annotation()
                {
                    Annotationid = Guid.NewGuid(),
                    Notetext = "This is a note",
                    Objectid = contactId,
                    Objectidtypecode = CRMQuery.Common.SystemEntityTypeCodes.Contact,
                    Isdocument = false
                };

                dc.Crm_Annotations.InsertOnSubmit(newNote);

                dc.SubmitChanges();
            }
        }
    }
}




